/* GLStringFactory.cpp
 *
 * --
 * Copyright (c) 2012, Christophe Huriaux
 * Distributed under the terms of the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * --
 */

#include <GL/gl.h>
#include <graphics/GLStringFactory.h>
#include <graphics/GLTextureManager.h>
#include <textures.h>
#include <debug/logger.h>

using namespace std;

GLStringFactory::GLStringFactory(int x, int y, const char* str)
	: str(str), x(x), y(y),
	  font(GLTextureManager::getInstance().getTexture(McTexture::FONT)),
	  stringVertices(NULL), texCoords(NULL), vertexArrayString(NULL)
{
	updateVerticesArray();
}


GLStringFactory::GLStringFactory(unsigned int fontId, int x, int y,
	const char* str)
	: str(str), x(x), y(y),
	  font(GLTextureManager::getInstance().getTexture(fontId)),
	  stringVertices(NULL), texCoords(NULL), vertexArrayString(NULL)
{

}

GLStringFactory::~GLStringFactory()
{
	if (stringVertices != NULL)
		delete stringVertices;

	if (texCoords != NULL)
		delete texCoords;

	if (vertexArrayString != NULL)
		delete vertexArrayString;
}


GLStringFactory&
GLStringFactory::setString(const char* s)
{
	str = std::string(s);
	updateVerticesArray();
	return *this;
}
GLStringFactory&
GLStringFactory::setString(std::string& s)
{
	str = s;
	updateVerticesArray();
	return *this;
}

GLStringFactory&
GLStringFactory::setFont(unsigned int id)
{
	font = GLTextureManager::getInstance().getTexture(id);
	return *this;
}

GLStringFactory&
GLStringFactory::setPosition(int x, int y)
{
	x = x;
	y = y;
	return *this;
}

void
GLStringFactory::display()
{
	glDepthMask(GL_FALSE);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	font->use();
	vertexArrayString->draw(GL_QUADS);
	glDisable(GL_BLEND);
	glDepthMask(GL_TRUE);
	glBindTexture(GL_TEXTURE_2D, 0);
}


void
GLStringFactory::updateVerticesArray()
{
	if (stringVertices != NULL)
		delete stringVertices;

	if (texCoords != NULL)
		delete texCoords;

	if (vertexArrayString != NULL)
		delete vertexArrayString;


	int len = str.size(),
	 eh = font->getElementHeight(),
	 ew = font->getElementWidth(),
	 shift = 0;

	vector2d *vInit = new vector2d[4*len];
	vector2d *tInit = new vector2d[4*len];
	stringVertices = new GLVertexDataLocal<vector2d>(4*len, 2);
	texCoords = new GLVertexDataLocal<vector2d>(4*len, 2);
	for (int i = 0; i < len; i++)
	{

		vInit[4*i+0] = vector2d(x+i*(ew+shift), y+eh);
		vInit[4*i+1] = vector2d(x+i*(ew+shift)+ew+shift*i, y+eh);
		vInit[4*i+2] = vector2d(x+i*(ew+shift)+ew, y);
		vInit[4*i+3] = vector2d(x+i*(ew+shift), y);

		tInit[4*i+0] = font->getCoord(GLTexture::TEX_TL, str[i]);
		tInit[4*i+1] = font->getCoord(GLTexture::TEX_TR, str[i]);
		tInit[4*i+2] = font->getCoord(GLTexture::TEX_BR, str[i]);
		tInit[4*i+3] = font->getCoord(GLTexture::TEX_BL, str[i]);
	}

	stringVertices->init(vInit);
	texCoords->init(tInit);

	delete[] vInit;
	delete[] tInit;

	vertexArrayString = new GLVertexArrayTexture<vector2d, vector2d>(stringVertices, texCoords);
}
